#pragma once

#include <asm/processor.h>

#define RCU_INITIALIZER(v) (__typeof__(*(v)) __force __rcu *)(v)

#define rcu_assign_pointer(p, v) \
    do                           \
    {                            \
        p = v;                   \
    } while (0)

#define RCU_INIT_POINTER(p, v)             \
    do                                     \
    {                                      \
        WRITE_ONCE(p, RCU_INITIALIZER(v)); \
    } while (0)

#define __rcu_dereference_raw(p, local)           \
    ({                                            \
        /* Dependency order vs. p above. */       \
        typeof(p) local = READ_ONCE(p);           \
        ((typeof(*p) __force __kernel *)(local)); \
    })

#define rcu_dereference_raw(p) __rcu_dereference_raw(p, __UNIQUE_ID(rcu))

static inline int rcu_read_lock_held(void)
{
    return 1;
}

#define __rcu_dereference_check(p, local, c, space)            \
    ({                                                         \
        /* Dependency order vs. p above. */                    \
        typeof(*p) *local = (typeof(*p) *__force)READ_ONCE(p); \
        ((typeof(*p) __force __kernel *)(local));              \
    })

#define rcu_dereference_check(p, c)                \
    __rcu_dereference_check((p), __UNIQUE_ID(rcu), \
                            (c) || rcu_read_lock_held(), __rcu)

void rcu_sched_clock_irq(int user);

void rcu_read_unlock(void);
void rcu_read_lock(void);
